package org.example.hrpc.rpc.core.impl;

import org.example.hrpc.common.URL;
import org.example.hrpc.common.exception.RemotingException;
import org.example.hrpc.common.exception.RpcException;
import org.example.hrpc.common.exception.TimeoutException;
import org.example.hrpc.rpc.client.TransportClient;
import org.example.hrpc.rpc.core.*;

import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class DefaultInvoker<T> extends AbstractInvoker<T> {
    private final TransportClient currentClient;
    private final Set<Invoker<?>> invokers;


    public DefaultInvoker(Class<T> serviceType, URL url, TransportClient client) {
        this(serviceType, url, client, null);
    }

    public DefaultInvoker(Class<T> serviceType, URL url, TransportClient client, Set<Invoker<?>> invokers) {
        super(serviceType, url);
        this.currentClient = client;
        this.invokers = invokers;
    }

    @Override
    protected Result  doInvoke(Invocation invocation) throws Throwable {
        RpcInvocation inv = (RpcInvocation) invocation;
        final String methodName = invocation.getMethodName();
        final int timeout = 10_000;
        final ExecutorService executor = Executors.newFixedThreadPool(10);
        boolean isOneway = false;
        if (isOneway) {
            return AsyncRpcResult.newDefaultAsyncResult(invocation);
        } else {
//                CompletableFuture<AppResponse> appResponseFuture =
//                        currentClient.request(inv, timeout, executor).thenApply(obj -> (AppResponse) obj);
            // 这里没问题，因为DefaultFuture 在 complete后的值类型是Result（实际上是AppResponse）
            CompletableFuture<AppResponse> appResponseFuture =
                    currentClient.sendRpc(inv, timeout, executor, null).thenApply(obj -> (AppResponse) obj);
            AsyncRpcResult result = new AsyncRpcResult(appResponseFuture, inv);
            result.setExecutor(executor);
            return result;
        }
    }
}
